﻿
Imports osi.root.constants
Imports osi.root.connector
Imports osi.root.delegates
Imports osi.root.procedure
Imports osi.root.formation
Imports osi.root.utils
Imports osi.service.convertor

Public Class block_dev_T_adapter(Of T)
    Implements dev_T(Of T)

    Public ReadOnly block_dev As block
    Private ReadOnly T_bytes As binder(Of _do_val_ref(Of T, Byte(), Boolean), bytes_conversion_binder_protector)
    Private ReadOnly bytes_T As binder(Of _do_val_ref(Of Byte(), T, Boolean), bytes_conversion_binder_protector)

    Public Sub New(ByVal b As block,
                   Optional ByVal T_bytes As binder(Of _do_val_ref(Of T, Byte(), Boolean), 
                                                       bytes_conversion_binder_protector) = Nothing,
                   Optional ByVal bytes_T As binder(Of _do_val_ref(Of Byte(), T, Boolean), 
                                                       bytes_conversion_binder_protector) = Nothing)
        assert(Not b Is Nothing)
        assert(T_bytes.has_value())
        assert(bytes_T.has_value())
        Me.block_dev = b
        Me.T_bytes = T_bytes
        Me.bytes_T = bytes_T
    End Sub

    Public Shared Function convert(ByVal i As block,
                                   ByRef o As dev_T(Of T),
                                   Optional ByVal T_bytes As binder(Of _do_val_ref(Of T, Byte(), Boolean), 
                                                                       bytes_conversion_binder_protector) = Nothing,
                                   Optional ByVal bytes_T As binder(Of _do_val_ref(Of Byte(), T, Boolean), 
                                                                       bytes_conversion_binder_protector) = Nothing) _
                                  As Boolean
        o = New block_dev_T_adapter(Of T)(i, T_bytes, bytes_T)
        Return True
    End Function

    Public Shared Function convert(ByVal i As block,
                                   ByVal o As pointer(Of dev_T(Of T)),
                                   Optional ByVal T_bytes As binder(Of _do_val_ref(Of T, Byte(), Boolean), 
                                                                       bytes_conversion_binder_protector) = Nothing,
                                   Optional ByVal bytes_T As binder(Of _do_val_ref(Of Byte(), T, Boolean), 
                                                                       bytes_conversion_binder_protector) = Nothing) _
                                  As event_comb
        Return sync_async(Function() As Boolean
                              Dim r As dev_T(Of T) = Nothing
                              Return convert(i, r, T_bytes, bytes_T) AndAlso
                                     eva(o, r)
                          End Function)
    End Function

    Public Shared Function convert(ByVal i As dev_T(Of T), ByRef o As block) As Boolean
        Dim a As block_dev_T_adapter(Of T) = Nothing
        If cast(i, a) AndAlso
           assert(Not a Is Nothing) Then
            o = a.block_dev
            Return True
        Else
            Return False
        End If
    End Function

    Public Function send(ByVal i As T) As event_comb Implements dev_T(Of T).send
        Dim ec As event_comb = Nothing
        Return New event_comb(Function() As Boolean
                                  Dim b() As Byte = Nothing
                                  If (+T_bytes)(i, b) Then
                                      ec = block_dev.send(b)
                                      Return waitfor(ec) AndAlso
                                             goto_next()
                                  Else
                                      Return False
                                  End If
                              End Function,
                              Function() As Boolean
                                  Return ec.end_result() AndAlso
                                         goto_end()
                              End Function)
    End Function

    Public Function receive(ByVal o As pointer(Of T)) As event_comb Implements dev_T(Of T).receive
        Dim ec As event_comb = Nothing
        Dim p As pointer(Of Byte()) = Nothing
        Return New event_comb(Function() As Boolean
                                  p = New pointer(Of Byte())()
                                  ec = block_dev.receive(p)
                                  Return waitfor(ec) AndAlso
                                         goto_next()
                              End Function,
                              Function() As Boolean
                                  Dim r As T = Nothing
                                  Return (+bytes_T)(+p, r) AndAlso
                                         eva(o, r) AndAlso
                                         goto_end()
                              End Function)
    End Function

    Public Function sense(ByVal pending As pointer(Of Boolean),
                          ByVal timeout_ms As Int64) As event_comb Implements dev_T(Of T).sense
        Return block_dev.sense(pending, timeout_ms)
    End Function
End Class
